using UnityEngine;

namespace GameToolkit.BehaviourTree
{
    [System.Serializable]
    [CompositeTitle("引用条件", Description = "引用条件")]
    [CompositeCategory]
    [DecorationCompositeOnly]
    internal class ConditionReference : LogicWithInputComposite, IWithoutInspectorComposite
    {
        [SerializeField, HideInInspector]
        internal CompositeState m_Input;

        internal override bool IsMultiInput => false;

        internal override CompositeState[] inputs
        {
            get
            {
                return new CompositeState[] { m_Input };
            }
            set
            {
                if (value != null && value.Length > 0)
                    m_Input = value[0];
            }
        }

        public override BehaviourTreeObject Create()
        {
            return new Impl();
        }

        class Impl : Decoration, IInterruptionSource
        {
            IInterruptionSource mInput;

            protected override void OnCreate(BehaviourTreePlayer player)
            {
            }

            protected override void OnDestroy(BehaviourTreePlayer player)
            {
            }

            internal override void InitializeSelf(CreateBehaviourTreeContext context)
            {
                base.InitializeSelf(context);
                mInput = context.interruptionBuffer.Count > 0 ? context.interruptionBuffer[0] : null;
            }

            internal override void InvokeCreateRecursive(BehaviourTreePlayer player)
            {
                if (mInput is BehaviourTreeObject obj)
                    obj.InvokeCreateRecursive(player);
                base.InvokeCreateRecursive(player);
            }

            internal override void InvokeDestroyRecursive(BehaviourTreePlayer player)
            {
                base.InvokeDestroyRecursive(player);
                if (mInput is BehaviourTreeObject obj)
                    obj.InvokeDestroyRecursive(player);
            }

            NodeState IInterruptionSource.GetInterruptResult(BehaviourTreePlayer player/*, ExecutableEntry attachNode*/)
            {
                if (mInput == null)
                    return NodeState.Running;
                else
                    return mInput.GetInterruptResult(player/*, attachNode*/);
            }

            NodeState IInterruptionSource.GetNotInterruptResult(BehaviourTreePlayer player/*, ExecutableEntry attachNode*/)
            {
                if (mInput == null)
                    return NodeState.Running;
                else
                    return mInput.GetNotInterruptResult(player/*, attachNode*/);
            }
        }
    }
}
